import numpy as np
import math
import random
from functools import reduce

''' 免疫优化算法求解主函数'''

# 算法基本参数
# 算法基本参数的给定 直接关系到输出结果
sizepop = 30  # 种群规模
overbest = 10  # 记忆库容量
MAXGEN = 20  # 迭代次数，也是最大进化代数
pcross = 0.5  # 交叉概率
pmutation = 0.4  # 变异概率
ps = 0.95  # 多样性评价参数
length = 6  # 配送中心数
M = sizepop + overbest  # 种群规模 + 记忆库容量
c = [0,0]
'''先构建距离dist()函数、test()函数、种群初始化popinit()函数、个体相似度similar()函数、
个体浓度值concentration()函数、excellence()函数'''


class test(object):
        # 两点间距离公式


    def dist(self,X,Y):
        return math.sqrt((X[0] - Y[0]) ** 2 + (X[1] - Y[1]) ** 2)


    # test()检查个体是否满足距离约束
    def test(self,code):
        city_coordinate = np.mat([[1304, 2312], [3639, 1315], [4177, 2244], [3712, 1399],
                                  [3488, 1535], [3326, 1556], [3238, 1229], [4196, 1044],
                                  [4312, 790], [4386, 570], [3007, 1970], [2562, 1756],
                                  [2788, 1491], [2381, 1676], [1332, 695], [3715, 1678],
                                  [3918, 2179], [4061, 2370], [3780, 2212], [3676, 2578],
                                  [4029, 2838], [4263, 2931], [3429, 1908], [3507, 2376],
                                  [3394, 2643], [3439, 3201], [2935, 3240], [3140, 3550],
                                  [2545, 2357], [2778, 2826], [2370, 2975]])
        print(type(city_coordinate))
        print(city_coordinate.shape)
        flag = 1
        aa = np.transpose(city_coordinate[code, :])
        #    if max(max(dis.pdist(aa)))>300:
        if max(max(self.dist(aa,c))) > 3000:
            flag = 0
        return  # 是否满足要求标志flag


    # 种群初始化函数（记忆库为空，全部随机产生）
    def popinit(self,n,length):  # n 为种群数量，length为抗体长度
        pop = np.zeros((n, length))
        for i in range(n):  # i 从0到n-1
            flag = 0
            while flag == 0:
                # 创建一个元素在0-1之间的，1*31的随机数矩阵,就相当于一个列表
                a_b = np.random.rand(1, 31)  # 返回多维数组型的随机数[[0. 0. ... 0. 0. ]]
                a = np.sort(a_b, axis=1)  # 将随机数按照行数从小到大排列,axis=0时按照列排，不写按行排
                b = np.argsort(a, axis=1)  # 返回a按行排的从小到大的索引值
                pop[i, :] = b[0, :length]
                # flag = test(pop[1,1])
            return pop  # pop:初始种群


a = test()
b = a.popinit(sizepop,length)
print("初始种群pop为：\n", b)
